Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting separate experience thresholds and max levels for each class #6414

Closed
wants to merge 13 commits into from

Conversation

ephphatha
Copy link
Contributor

Builds on #6399, this allows using a D2 style Experience.txt file to let each class level up at different thresholds with and potentially different max levels.

This does come with a significant penalty to memory usage (6 vectors of 32 bit values with usually 50 entries each) which doesn't help with getting it to run on low-end hardware... Could probably make the lookup logic more complicated to save on space required when there's a lot of duplication.

@julealgon
Copy link
Contributor

Really cool to see softcoding start to happen for the project. Personally not a big fan of CSV for this (would much rather push for Json) but that's not up to me really and not that important comparatively.

@DakkJaniels
Copy link
Contributor

DakkJaniels commented Jul 28, 2023

If we do per-class experience, would it makes sense to just separate out the text file on a per-class basis? Basically putting all the data files relevant to a character class in it's own folder? I figure this would make it easier to understand what you'd have to provide for each character class.

@julealgon
Copy link
Contributor

If we do per-class experience, would it makes sense to just separate out the text file on a per-class basis? Basically putting all the data files relevant to a character class in it's own folder? I figure this would make it easier to understand what you'd have to provide for each character class.

Keep in mind that there is also an argument for keeping all in the same place so you can easily compare them etc.

Additionally, having separate files with this proposed mechanism will add some (slight) coding overhead as well and thus (slightly) worse for maintenance purposes, as each 'categorization' we come up with will require dedicated code to support it.

Not sure who is used to .NET Core here, but a system similar to Extensions.Configuration would avoid some of this by allowing arbitrary file splitting while keeping the configuration reading aspect independent. Might be something to consider maybe for a future enhancement. The way configuration works in .NET now makes it so that the application becomes agnostic about where the configuration is coming from, which is a rather nice design for a configuration system (as mentioned above, allows things such as creating as many config files as one wants, or just one, or allows overrides via cmdline arguments, or environment variables, etc). It additionally allows different formats to be provided as well, such as json, csv, ini, etc, without impacting the read side at all.

Not saying it is a bad idea necessarily... just raising that there are pros and cons that have to be considered.

@ephphatha
Copy link
Contributor Author

ephphatha commented Jul 28, 2023 via email

@DakkJaniels
Copy link
Contributor

Additionally, having separate files with this proposed mechanism will add some (slight) coding overhead as well and thus (slightly) worse for maintenance purposes, as each 'categorization' we come up with will require dedicated code to support it.

Why would that be the case vs. what's here now? Wouldn't you also need coding overhead for processing the various files of each type? I would think looking for the class folder and then processing the files in that folder should be minimal additional code.

The way I was imagining it was that you just have folders for each class, with a text file for each thing you are defining (whether that's experience, or frame information, or stats or whatever). Then if you wanted to make a new class, you could just copy and paste a folder and then edit all the files accordingly, rather than hunting for the location in each file where you have to add in the necessary info.

In terms of comparing the info between classes, that should be easy enough in a spreadsheet editor, or some tooling should be simple enough to create to do that.

This implementation was intended as (the first step in) a straight port of Diablo 2's text files into DevilutionX. The example file uses Diablo/Hellfire class names instead of Diablo 2 classes and experience levels but is otherwise identical. The aim was to reimplement as much of that as possible so that people familiar with that style of modding can jump straight in.

I was just throwing out an idea for organization, I appreciate the work 🙂

@julealgon
Copy link
Contributor

Additionally, having separate files with this proposed mechanism will add some (slight) coding overhead as well and thus (slightly) worse for maintenance purposes, as each 'categorization' we come up with will require dedicated code to support it.

Why would that be the case vs. what's here now? Wouldn't you also need coding overhead for processing the various files of each type? I would think looking for the class folder and then processing the files in that folder should be minimal additional code.

Correct, which is why I said "slightly" 😆 . It has some impact, but it is admittedly pretty small.

The way I was imagining it was that you just have folders for each class, with a text file for each thing you are defining (whether that's experience, or frame information, or stats or whatever). Then if you wanted to make a new class, you could just copy and paste a folder and then edit all the files accordingly, rather than hunting for the location in each file where you have to add in the necessary info.

Which again... is totally fine. The caveat is that there are many different ways to categorize the same data. For example, you could also have a single configuration file for each class where each "area" (experience, frame data, etc) is a section in the file instead of being a completely separate file. However, that only works with Json as each "area" has a different data structure.

In terms of comparing the info between classes, that should be easy enough in a spreadsheet editor, or some tooling should be simple enough to create to do that.

Who is going to write the tooling though? Again, I don't disagree, but needing another tool to handle it adds effort. Perhaps it would be more sensible to split the file after the tooling is in place?

@DakkJaniels
Copy link
Contributor

Which again... is totally fine. The caveat is that there are many different ways to categorize the same data. For example, you could also have a single configuration file for each class where each "area" (experience, frame data, etc) is a section in the file instead of being a completely separate file. However, that only works with Json as each "area" has a different data structure.

Sure, that would be great if we were doing json, but it doesn't seem like that's the plan at the moment.

Who is going to write the tooling though? Again, I don't disagree, but needing another tool to handle it adds effort. Perhaps it would be more sensible to split the file after the tooling is in place?

The person who is modding the game who needs to do these comparisons between classes?

@julealgon
Copy link
Contributor

Sure, that would be great if we were doing json, but it doesn't seem like that's the plan at the moment.

Fair.

Who is going to write the tooling though? Again, I don't disagree, but needing another tool to handle it adds effort. Perhaps it would be more sensible to split the file after the tooling is in place?

The person who is modding the game who needs to do these comparisons between classes?

I think this is a bit of a tall ask considering the scope of this project though. And again, if tooling was involved, then the underlying format and distribution of the files wouldn't really matter that much at all in the first place, since the tool would just abstract it away.

In a sense, your argument for a tool actually serves as a counterpoint against your argument for splitting the files IMHO.

@DakkJaniels
Copy link
Contributor

DakkJaniels commented Jul 28, 2023

I think this is a bit of a tall ask considering the scope of this project though. And again, if tooling was involved, then the underlying format and distribution of the files wouldn't really matter that much at all in the first place, since the tool would just abstract it away.
In a sense, your argument for a tool actually serves as a counterpoint against your argument for splitting the files IMHO.

I'm not sure how that follows from what I said - I'm not putting anything on the project, nor would that kind of tooling be required.

The organizational structure that is most beneficial (from a modding standpoint) really depends on the kind modding one is looking to make. If someone is looking to add new classes, I would think it is much easier to grab a folder with all the class related info and modify it accordingly. If someone is just looking to modify existing classes and the balance between classes is important, they may prefer to have the information for a particular thing centralized for all the classes.

All I was saying was that if it is important to a modder that they have all this information centralized, the modder could certainly make a tool to do so. It is not at all necessary.

@julealgon
Copy link
Contributor

All I was saying was that if it is important to a modder that they have all this information centralized, the modder could certainly make a tool to do so. It is not at all necessary.

I thought you were suggesting that the tool would come from DevilutionX itself.

All I was saying was that if it is important to a modder that they have all this information centralized, the modder could certainly make a tool to do so. It is not at all necessary.

Couldn't you say the exact same thing for the opposite as well? If a modder thought it was important to have the information separated, he could make a tool for that.

I digress though. I don't really mind what you end up with in this particular case, both options are ok and have pros and cons to a point where I actually don't have a strong preference.

@FitzRoyX
Copy link

I like the idea of having the game's data tables externalized into csv, but not the class-based leveling stuff. I can't think of anything that would do but make both gameplay more confusing and modding more laborious.

@julealgon
Copy link
Contributor

I like the idea of having the game's data tables externalized into csv, but not the class-based leveling stuff. I can't think of anything that would do but make both gameplay more confusing and modding more laborious.

I'm not following this. You are saying you are in favor of softcoding the data, but not this particular piece of data? Or are you just not in favor of splitting the table per class and would instead want a single table for every class?

@FitzRoyX
Copy link

FitzRoyX commented Aug 1, 2023

I like the idea of having the game's data tables externalized into csv, but not the class-based leveling stuff. I can't think of anything that would do but make both gameplay more confusing and modding more laborious.

I'm not following this. You are saying you are in favor of softcoding the data, but not this particular piece of data? Or are you just not in favor of splitting the table per class and would instead want a single table for every class?

I like the single table. I don't think changing values should require changing them 6 times.

@julealgon
Copy link
Contributor

I like the single table. I don't think changing values should require changing them 6 times.

I see now. I honestly tend to agree with you in principle. I think an ideal configuration system would allow you to either change it globally, or override it for a specific class. Again, going back to the system I mentioned from .NET, you could do this by introducing separate files something like:

configBuilder
    .AddCsv("experienceLevels.csv")
    .AddCsv("experienceLevels.{characterClass}.csv", optional: true)

This would load experienceLevels.csv first, and then look for a class-specific override, for example experienceLevels.warrior.csv, when you select the Warrrior class, which would override any values from the main table if present, and only do so for specific entries that are found. This allows one to customize each individual value separately, or all together.

The code that depends on the configuration doesn't need to change at all, being agnostic of how the files are setup, how they override each other, etc. What matters is just the final configuration setting name.

@ephphatha
Copy link
Contributor Author

With #6608 we've gone with a file-per-class structure which would require a different approach than proposed in this PR.

@ephphatha ephphatha closed this Sep 23, 2023
@AJenbo
Copy link
Member

AJenbo commented Sep 23, 2023

Does Diablo 2 have different experience tables per class? I'm a little confused as this feature appears a bit unusual to me.

@ChaosMarc
Copy link
Contributor

Yes is does. There is a file with a column for each character. In vanilla all columns are the same though and I don't know any mod that features distinct experience curves

@julealgon
Copy link
Contributor

I'm a little confused as this feature appears a bit unusual to me.

It's not completely unusual for games to have characters with different experience thresholds. One that comes to mind is Final Fantasy IV where level requirements vary quite a bit per character.

Having the possibility to configure experience thresholds per class makes a lot of sense for modding possibilities IMHO, even if in most cases they end up being the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants